package com.cj.media.mediacodec

import android.media.MediaCodec
import android.media.MediaCodecInfo
import android.media.MediaFormat
import com.cj.media.mediacodec.utils.FileUtils

class CameraEncoder(private val width:Int,private val height:Int,private val filePathH264:String,private val filePathTxt:String) {

    //编码器
    private var mediaCodec:MediaCodec
    private var index:Int = 0

    init {
        mediaCodec = MediaCodec.createEncoderByType("video/avc")
        //编码
        val format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC,width, height)
        //1s 20帧数据
        format.setInteger(MediaFormat.KEY_FRAME_RATE,15)
        //30帧一个I帧
        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,2)
        //码率 ，1s编码出来的字节码数
        format.setInteger(MediaFormat.KEY_BIT_RATE,width * height)
        //数据来源，数据来自摄像头，摄像头采集的数据是YUV
        format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible)
        //编码标志位
        mediaCodec.configure(format,null,null, MediaCodec.CONFIGURE_FLAG_ENCODE)//CONFIGURE_FLAG_ENCODE表示编码
        mediaCodec.start()
    }

     fun encodeFrame(input:ByteArray) {
         //输入
         //寻找空闲的输入缓存
         val inputBufferIndex = mediaCodec.dequeueInputBuffer(10000)
         val info = MediaCodec.BufferInfo()
         if(inputBufferIndex > 0){
             val inputBuffer = mediaCodec.getInputBuffer(inputBufferIndex)?:return
             inputBuffer.clear()
             inputBuffer.put(input)
            mediaCodec.queueInputBuffer(inputBufferIndex,0,input.size,computePts(),0)
             index ++
         }

         //输出
         val outputBufferIndex = mediaCodec.dequeueOutputBuffer(info,100000)
         if(outputBufferIndex >= 0){
             val outputBuffer = mediaCodec.getOutputBuffer(outputBufferIndex)?:return
             val bytes = ByteArray(info.size)
             outputBuffer.get(bytes)
             FileUtils.writeBytes(bytes,/*filePathH264*/null)
             FileUtils.writeContent(bytes,/*filePathTxt*/null)
             mediaCodec.releaseOutputBuffer(outputBufferIndex,false)
         }
    }

    private fun computePts():Long{
        return 1000000L / 15 * index
    }
}